#include "stdafx.h"
//-------------------------------------------------------------------------------------------------
//ImageType.cpp  - Behaviour and data of an Image        
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2011 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk Sept 2011
//
//----Comments-------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
#include "ImageType.h"

const char * const ImageType::unclassified = "(Unclassified)";						//there is always an unclassified image type
																			//XML naming
const char * const ImageType::xmlImageTypes = "ImageTypes";							//collection of image types in this dataset
const char * const ImageType::xmlImageTypesName = "Name";							//name attribute for collection of image types in this dataset
const char * const ImageType::xmlImageType = "ImageType";							//a specific image type of this dataset
const char * const ImageType::xmlImageTypeImageObjects = "ImageTypeImageObjects";   //image object types found in this type of image
const char * const ImageType::xmlImageTypeImageObject = "ImageTypeImageObject";		//a specific image object type found in this type of image
const char * const ImageType::xmlImageTypeProps = "ImageTypeProps";					//image properties found in this type of image
const char * const ImageType::xmlImageTypeProp = "ImageTypeProp";					//a specific image property found in this type of image	

ImageType::ImageType(void):
	_Name("")
{
}


ImageType::ImageType(const char *name) 
{
	_Name = name;
}

ImageType::~ImageType(void)
{
	ClearAllLists();
}


ImageType *ImageType::CreateImageType(TiXmlElement *xmlImageType, ResourceList &resourceList) 
{
	ImageType *rc = '\0';

	std::string typeName = (xmlImageType == '\0') ? ImageType::unclassified : xmlImageType->GetText();
	if (typeName.length() > 0 )
	{
		if ((rc = new ImageType(typeName.c_str())) != '\0') //, pObserver)) != '\0')
		{
			if (xmlImageType != '\0')
			{
				for( TiXmlNode *child = xmlImageType->FirstChild(); child; child = child->NextSibling() )
				{
					if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
					{
						TiXmlElement *xmlImageTypeComponent = dynamic_cast<TiXmlElement *>(child);
						if ( xmlImageTypeComponent != '\0' )
						{
							std::string ImageTypeComponentName = xmlImageTypeComponent->Value();

							if ( ImageTypeComponentName == ImageType::xmlImageTypeProps)
								rc->AddProperties(xmlImageTypeComponent);
							else
							{
								if ( ImageTypeComponentName == ImageType::xmlImageTypeImageObjects)
									rc->AddImageObjectTypes(xmlImageTypeComponent, resourceList);
							}
						}
					}
				}
			}
		}
	}
	return rc;
}


ImageObjectType *ImageType::LookupImageObjectType (const char *name)
{
	ImageObjectType *rc = '\0';

	if ( name != '\0' )
	{
		size_t cnt = _ImageObjTypes.size();
		for (size_t x = 0; x < cnt; x++)
		{
			if (strcmp(  _ImageObjTypes[x]->GetName(), name) == 0 )
			{
				rc = _ImageObjTypes[x];
				break;
			}
		}
	}
	return rc;
}

ImageObjectType *ImageType::GetImageObjectTypeForMenuId( int Id)
{
	ImageObjectType *rc = '\0';

	size_t cnt = _ImageObjTypes.size();
	for (size_t x = 0; x < cnt; x++)
	{
		if (_ImageObjTypes[x]->GetResourceId() == Id )
		{
			rc = _ImageObjTypes[x];
			break;
		}
	}

	return rc;
}


bool ImageType::HasProperty(ImageProp *pImageProp)
{
	bool rc = false;

	if ( pImageProp != '\0' )
	{
		std::string propName = pImageProp->GetPropName();
		size_t cnt = _ImageTypeProps.size();
		for (size_t x = 0; x < cnt; x++)
		{
			if (propName == _ImageTypeProps[x]->GetName() )
			{
				rc = true;
				break;
			}
		}
	}
	return rc;
}

ImageTypeProp *ImageType::LookupProperty (const char *name)
{
	ImageTypeProp *rc = '\0';

	if ( name != '\0' )
	{
		std::string propName = name;
		size_t cnt = _ImageTypeProps.size();
		for (size_t x = 0; x < cnt; x++)
		{
			if (propName == _ImageTypeProps[x]->GetName() )
			{
				rc = _ImageTypeProps[x];
				break;
			}
		}
	}
	return rc;
}

//............................................................................................
//private member functions
//............................................................................................

void ImageType::AddProperties(TiXmlElement *xmlImageTypeProps)
{
	for( TiXmlNode *child = xmlImageTypeProps->FirstChild(); child; child = child->NextSibling() )
	{
		if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
		{
			TiXmlElement *xmlImageTypeProp = dynamic_cast<TiXmlElement *>(child);
			if ( xmlImageTypeProp != '\0' )
			{
				ImageTypeProp *pImageTypeProp = '\0';
				std::string ImageTypePropName = xmlImageTypeProp->Value();
				if ( ImageTypePropName == ImageType::xmlImageTypeProp)
				{
					if ( (pImageTypeProp = ImageTypeProp::CreateImageTypeProp(xmlImageTypeProp, ImageType::xmlImageType)) != '\0')
					{
						if ( AddProperty(pImageTypeProp) == false)
							delete pImageTypeProp;
					}
				}
			}
		}
	}
}

bool ImageType::AddProperty (ImageTypeProp *pImageTypeProp )
{
	bool rc = false;

	if ( LookupProperty (pImageTypeProp->GetName()) == '\0')
	{
		_ImageTypeProps.push_back(pImageTypeProp);
		rc = true;
	}

	return rc;

}

void ImageType::AddImageObjectTypes (TiXmlElement *xmlImageTypeImageObjects, ResourceList &resourceList )
{
	ImageObjectType *pImageObjType = '\0';

	//always create a select image object type
	if ( (pImageObjType = ImageObjectType::CreateImageObjectType('\0', resourceList)) != '\0')	
	{
		if ( AddImageObjectType(pImageObjType) == false)
			delete pImageObjType;
	}

	//now create image object types as specified for this type of image in xml
	for( TiXmlNode *child = xmlImageTypeImageObjects->FirstChild(); child; child = child->NextSibling() )
	{
		if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
		{
			TiXmlElement *xmlImageObjectType = dynamic_cast<TiXmlElement *>(child);
			if ( xmlImageObjectType != '\0' )
			{
	
				std::string ImageObjectTypeName = xmlImageObjectType->Value();
				if ( ImageObjectTypeName == ImageType::xmlImageTypeImageObject)
				{
					if ( (pImageObjType = ImageObjectType::CreateImageObjectType(xmlImageObjectType, resourceList)) != '\0')
					{
						if ( AddImageObjectType(pImageObjType) == false)
							delete pImageObjType;
					}
				}
			}
		}
	}
	return;
}

bool ImageType::AddImageObjectType (ImageObjectType *pObjectType )
{
	bool rc = false;

	if ( LookupImageObjectType (pObjectType->GetName()) == '\0')
	{
		_ImageObjTypes.push_back(pObjectType);
		rc = true;
	}

	return rc;
}


bool ImageType::ClearAllLists()
{
	bool rc = false;

	size_t cnt = _ImageObjTypes.size();
	if (cnt > 0 )
	{
		for (size_t x = 0; x < cnt; x++)
			delete  _ImageObjTypes[x];
		_ImageObjTypes.clear();
		rc = true;
	}

	cnt = _ImageTypeProps.size();
	if (cnt > 0 )
	{
		rc = false;
		for (size_t x = 0; x < cnt; x++)
			delete _ImageTypeProps[x];
		_ImageTypeProps.clear();
		rc = true;
	}
	return rc;
}



//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------